package spectra.ee.web.common.service;

import java.sql.SQLException;

import java.util.List;
import com.ibatis.sqlmap.client.SqlMapClient;

import spectra.base.log.LP;
import spectra.base.log.Logger;
import spectra.base.sql.ibatis.SqlMapperWeb;
import spectra.base.util.DateUtil;
import spectra.ee.commons.qna.model.Qna;
import spectra.ee.commons.qna.model.QnaProcess;
import spectra.ee.web.common.model.Survey;
import spectra.ee.web.common.model.SurveyResponse;
import spectra.ee.web.common.model.Option;
import spectra.ee.web.kb.model.Kb;

/**
 * 설문 관리 클래스.
 *
 * @author shyun
 */
public class SurveyServiceBase
{

    /** Logger객체. */
    private static Logger logger = Logger.getLoggerInstance(SurveyServiceBase.class.getName());

    /** SqlMapClient 객체. */
    protected static SqlMapClient sqlMap = SqlMapperWeb.getSqlMapWebInstance();

    /**
     * 검색설문 중복 체크.
     *
     * @param logId 로그ID.
     * @param surveyItemId 설문아이템ID.
     * @return 중복이면 true, 아니면 false
     */
    public boolean selectCountByTargetId(String logId, String surveyItemId)
    {
        //add by jbyun(2008. 12. 29)
        //TODO : [jbyun] 검색결과설문 중복체크를 위해서 t_survey_response테이블의
        //suveyItemId + targetId 를 조합으로 체크하도록 수정
        boolean isDuble = false;
        SurveyResponse obj = new SurveyResponse();
        obj.setSurveyItemId(surveyItemId);
        obj.setTargetId(logId);

        try
        {
            Integer iRet = (Integer) sqlMap.queryForObject("Survey.selectCountByTargetId", obj);
            if (iRet.intValue() > 0) isDuble = true;
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }

        return isDuble;
    }

    /**
     * 주어진 도메인ID와 서비스타입에 해당하는 모든 설문 목록을 가져오는 메소드.
     *
     * @param domainId 도메인ID.
     * @param nodeId 노드ID.
     * @param serviceType 서비스타입.
     * @param surveyType 설문타입.
     * @param qnaId QnA ID.
     *
     * @return List 설문 목록.
     */
    public List selectSurveyListByCondition(String domainId, String nodeId, String serviceType, String surveyType, String qnaId)
    {
        List list = null;
        Survey obj = new Survey();
        obj.setDomainId(domainId);
        obj.setNodeId(nodeId);
        obj.setServiceType(serviceType);
        obj.setSurveyType(surveyType);
        obj.setQnaId(qnaId); // QNA에서 설문에 참여했을 경우 입력값을 가져오기 위함
        obj.setCurrentDate(DateUtil.getCurrDateTimeStamp());

        try
        {
            if (nodeId == null || nodeId.length() == 0)
            {
                //add by jbyun. {2008. 12. 29}
                //TODO : 고객센터 통합검색(전체검색(node == null))이면, 카테고리에 연결된 설문은 찾지 않고 도메인에 연결된 설문만 찾도록 수정.
                list = (List) sqlMap.queryForList("Survey.selectSurveyFormListByDomainId", obj);
            }
            else
            {
                list = (List) sqlMap.queryForList("Survey.selectSurveyFormList", obj);
                if (list.size() <= 0)
                {
                    list = (List) sqlMap.queryForList("Survey.selectSurveyFormListByDomainId", obj);
                }
            }
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return list;
    }

    /**
     * 설문 타입이 CODES 일때 CODE LIST 를 가져오는 메소드.
     *
     * @param codeSetId 코드셋ID.
     * @return CaseInsensitiveMap List.<br>
     * codeset_id:코드셋아이디.<br>
     * code_id:코드아이디.<br>
     * parent_id:부모아이디.<br>
     * code_name:코드이름.<br>
     * depth:깊이.<br>
     * report_code:통계코드.<br>
     * code_value:코드값.<br>
     * sort_order:정렬순서.<br>
     * delete_flag:삭제여부.<br>
     */
    public List selectSurveyCodeList(String codeSetId)
    {
        List list = null;
        Survey obj = new Survey();
        obj.setCodeSetId(codeSetId);
        try
        {
            list = (List) sqlMap.queryForList("Survey.selectSurveyCodeList", obj);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return list;
    }

    /**
     * 설문 타입이 매핑일때 매핑 정보를 가져오는 메소드.
     *
     * @param mappingId 메핑ID.
     *
     * @return CaseInsensitiveMap List.<br>
     * mapping_id:설문맵핑아이디.<br>
     * mapping_name:설문맵핑이름.<br>
     * service_type:서비스타입.<br>
     * mapping_type:맵핑타입.<br>
     * target_table:타겟테이블.<br>
     * target_field:타겟필드.<br>
     */
    public List selectSurveyMappingInfo(String mappingId)
    {
        List list = null;
        Survey obj = new Survey();
        obj.setMappingId(mappingId);
        try
        {
            list = (List) sqlMap.queryForList("Survey.selectSurveyMappingInfo", obj);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return list;
    }

    /**
     * t_survey_response 에 설문을 입력하는 메소드.
     *
     * @param survey SurveyResponse객체.
     *
     * @return boolean 성공시 true, 실패시 false.
     */
    public boolean insertSurveyResponse(SurveyResponse survey)
    {
        boolean bSuccess = false;
        try
        {
            sqlMap.startTransaction();
            sqlMap.insert("Survey.insertServeyResponse", survey);
            sqlMap.commitTransaction();
            bSuccess = true;
        }
        catch(Exception e)
        {
            logger.error(e.getMessage());
            e.printStackTrace();
        }
        finally
        {
            try
            {
                sqlMap.endTransaction();
            }
            catch(SQLException e)
            {
                logger.error(e.getMessage());
                e.printStackTrace();
            }
        }

        return bSuccess;
    }

    /**
     * kbId로 만족도를 업데이트.
     *
     * @param serviceType 서비스타입.
     * @param kbId 지식ID.
     * @param codeValue 코드값.
     *
     * @return boolean 성공시 true, 실패시 false.
     */
    public boolean updateKbDetail(String serviceType, String kbId, String codeValue)
    {
        boolean result = false;
        int iResult = -1;
        Kb obj = new Kb();
        obj.setServiceType(serviceType);
        obj.setKbId(kbId);
        obj.setTotalFeedback(Integer.parseInt(codeValue));
        try
        {
            sqlMap.startTransaction();
            iResult = sqlMap.update("Survey.updateKbDetail", obj);
            sqlMap.commitTransaction();
            if(iResult > 0)
            {
                result = true;
            }
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        finally
        {
            try
            {
                sqlMap.endTransaction();
            }
            catch(SQLException e)
            {
                logger.error(e.getMessage());
            }
        }
        return result;
    }

     /**
      * kb_view_log를 업데이트 하는 메소드.
      *
      * @param logId 로그ID.
      * @param codeValue 코드값.
      * @param codeId 코드ID.
      *
      * @return boolean 성공시 true, 실패시 false.
      */
    public boolean updateKbViewLog(String logId, String codeValue, String codeId)
    {
        boolean result = false;
        int iResult = -1;
        Kb obj = new Kb();
        obj.setLogId(logId);
        obj.setFeedback(Integer.parseInt(codeValue));
        obj.setFeedbackCodeId(codeId);
        try
        {
            sqlMap.startTransaction();
            iResult = sqlMap.update("Survey.updateKbViewLog", obj);
            sqlMap.commitTransaction();
            if(iResult > 0)
            {
                result = true;
            }
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        finally
        {
            try
            {
                sqlMap.endTransaction();
            }
            catch(SQLException e)
            {
                logger.error(e.getMessage());
            }
        }
        return result;
    }

    /**
     * kb_search_log를 업데이트 하는 메소드.
     *
     * @param logId 로그ID.
     * @param codeValue 코드값.
     * @param codeId 코드ID.
     *
     * @return boolean 성공시 true, 실패시 false.
     */
    public boolean updateSearchLog(String logId, String codeValue, String codeId)
    {
        boolean result = false;
        int iResult = -1;
        Kb obj = new Kb();
        obj.setLogId(logId);
        obj.setFeedback(Integer.parseInt(codeValue));
        obj.setFeedbackCodeId(codeId);

        try
        {
            sqlMap.startTransaction();
            iResult = sqlMap.update("Survey.updateKbSearchLog", obj);
            sqlMap.commitTransaction();
            if(iResult > 0)
            {
                result = true;
            }
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        finally
        {
            try
            {
                sqlMap.endTransaction();
            }
            catch(SQLException e)
            {
                logger.error(e.getMessage());
            }
        }
        return result;
    }

    /**
     * QNA 만족도 업데이트.
     *
     * @param processSeq 프로세스시퀀스.
     * @param feedback 만족도.
     * @param feedbackCodeId 만족도코드ID.
     * @param qnaId Qna아이디.
     *
     * @return boolean 성공시 true, 실패시 false.
     */
    public boolean updateQnaFeedback(String qnaId, int processSeq, int feedback, String feedbackCodeId)
    {
        boolean bSuccess = false;
        int iResult = -1;
        String strCurrentDate = DateUtil.getCurrDateTimeStamp();

        Qna qna = new Qna();
        qna.setTotalFeedback(feedback);
        qna.setQnaId(qnaId);

        QnaProcess qnaProcess = new QnaProcess();
        qnaProcess.setFeedback(feedback);
        qnaProcess.setFeedbackDate(strCurrentDate);
        qnaProcess.setFeedbackCodeId(feedbackCodeId);
        qnaProcess.setQnaId(qnaId);
        qnaProcess.setProcessSeq(processSeq);

        try
        {
            sqlMap.startTransaction();
            iResult = sqlMap.update("Survey.updateQnaFeedback", qna);
            iResult = sqlMap.update("Survey.updateQnaProcessFeedback", qnaProcess);
            sqlMap.commitTransaction();
            if(iResult > 0)
            {
                bSuccess = true;
            }
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        finally
        {
            try
            {
                sqlMap.endTransaction();
            }
            catch(SQLException e)
            {
                logger.error(e.getMessage());
            }
        }

        return bSuccess;
    }

    /**
     * 설문 타입이 매핑일때 매핑 정보를 업데이트 하는 메소드.
     *
     * @param targetId 타겟ID.
     * @param mappingType 맵핑타입.
     * @param targetTable 타겟테이블.
     * @param targetField 타겟필드.
     * @param responseValue 응답값.
     *
     * @return boolean 성공시 true, 실패시 false.
     */
    public boolean updateMappingInfo(String targetId, String mappingType, String targetTable, String targetField, String responseValue)
    {
        boolean result = false;
        int iResult = -1;
        SurveyResponse obj = new SurveyResponse();
        obj.setMappingType(mappingType);
        obj.setTargetTable(targetTable);
        obj.setTargetField(targetField);
        obj.setResponseValue(responseValue);
        obj.setCreatedDate(DateUtil.getCurrDateTimeStamp());
        obj.setTargetId(targetId);

        try
        {
            sqlMap.startTransaction();
            iResult = sqlMap.update("Survey.updateMappingInfo", obj);
            sqlMap.commitTransaction();
            if(iResult > 0)
            {
                result = true;
            }
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        finally
        {
            try
            {
                sqlMap.endTransaction();
            }
            catch(SQLException e)
            {
                logger.error(e.getMessage());
            }
        }
        return result;
    }

    /**
    * <pre>
    * t_survey_response 에 targetId로 설문 등록한 내용이 있는지 알아보는 메소드
    * </pre>.
    *
    * @param targetId 타겟ID.
    * @param serviceType 서비스타입.
    * @param surveyType 설문타입.
    * @param iProcessSeq 프로세스시퀀스.
    *
    * @return List 타겟ID로 반환된 설문리스트.
    *
    * @throws Exception
    */
    public List selectSurveyResponseByTargetId(String targetId, int iProcessSeq, String serviceType, String surveyType)
    {
        List list = null;

        SurveyResponse obj = new SurveyResponse();
        obj.setTargetId(targetId);
        obj.setProcessSeq(iProcessSeq);
        obj.setServiceType(serviceType);
        obj.setSurveyType(surveyType);

        try
        {
            list = sqlMap.queryForList("Survey.selectSurveyResponseByTargetId", obj);
        }
        catch(SQLException e)
        {
            logger.error(e.getMessage());
        }

        return list;
    }

    /**
    * targetId와 processSeq로 설문 정보를 알아온다.
    *
    * @param targetId 타겟ID.
    * @param processSeq 프로세스시퀀스.
    *
    * @return qna객체.
    */
    public Qna selectSurveyInfoByTargetId(String targetId, int processSeq)
    {
        Qna qna = new Qna();

        QnaProcess obj = new QnaProcess();
        obj.setQnaId(targetId);
        obj.setProcessSeq(processSeq);

        try
        {
            qna = (Qna) sqlMap.queryForObject("Survey.selectSurveyInfoByTargetId", obj);
        }
        catch(SQLException e)
        {
            logger.error(e.getMessage());
        }

        return qna;
    }

    /**
     * 주어진 insert 쿼리를 수행한다.
     * @param query insert 쿼리
     * @return 성공/실패 여부
     */
    public boolean insertWithQuery(String query)
    {
        boolean bSuccess = false;
        try
        {
            sqlMap.startTransaction();
            sqlMap.insert("Survey.insertWithQuery", query);
            sqlMap.commitTransaction();
            bSuccess = true;
        }
        catch(Exception e)
        {
            logger.error(e.getMessage());
            e.printStackTrace();
        }
        finally
        {
            try
            {
                sqlMap.endTransaction();
            }
            catch(SQLException e)
            {
                logger.error(e.getMessage());
                e.printStackTrace();
            }
        }

        return bSuccess;
    }
    

    /**
     * 주어진 insert 쿼리를 수행한다.
     * @param option 옵션 추가정보를 담은 옵션 객체
     * @return 성공/실패 여부
     */
    public boolean insertOrUpdateOption(Option option)
    {
        boolean bSuccess = false;
        try
        {
            sqlMap.startTransaction();
            sqlMap.insert("Survey.insertOptionQuery", option);
            sqlMap.commitTransaction();
            bSuccess = true;
        }
        catch(Exception e)
        {
            logger.info(LP.NOTE, "Survey.insertOptionQuery error. so, execute updateOptionQuery.");
        }
        finally
        {
            try
            {
                sqlMap.endTransaction();
            }
            catch(SQLException e)
            {
                logger.error(LP.NOTE, "Survey.insertOptionQuery - endTransaction Error !!",  e);
            }
        }
        
        if( !bSuccess )
        {
            try
            {
                sqlMap.startTransaction();
                sqlMap.insert("Survey.updateOptionQuery", option);
                sqlMap.commitTransaction();
                bSuccess = true;
            }
            catch(Exception e)
            {
                logger.error(LP.NOTE, "Survey.updateOptionQuery Error !!",  e);
            }
            finally
            {
                try
                {
                    sqlMap.endTransaction();
                }
                catch(SQLException e)
                {
                    logger.error(LP.NOTE, "Survey.updateOptionQuery - endTransaction Error !!",  e);
                }
            }
        }

        return bSuccess;
    }    
}